<?php
/**
* object-oriented file system manipulation as nodes.
* This file belongs to a webappkit package (kit)
* @link http://webappkit.net
* @package pathnodes
* @subpackage common
* @author J.Ducastel <jeremie@ducastel.name>
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
*/

/**
* object-oriented file system manipulation as nodes.
* This is the root class
* @author J.Ducastel <jeremie@ducastel.name>
*/
class pathNode {
/*------------------------------------------------------------------------------
                                                                     constructor
------------------------------------------------------------------------------*/
	/**
	* use pathNode::getNode to get an appropriate instance
	* @access private
	*/
	function pathNode($path=null) {
		$this->__construct($path);
	}/**/

	/**
	* "real" constructor.
	* use parent::__construct in subclasses to call parent constructor
	* @access private
	*/
	function __construct($path=null) {
		// setting own info
		if (is_string($path))
			$this->setInfo($path);
	}
/*------------------------------------------------------------------------------
                                                                  public methods
------------------------------------------------------------------------------*/
	/**
	* returns appropriate instance of pathNode or pathNode subclass
	* @static
	* @param string $path
	* @access public
	* @return pathNode and pathnodes descendant instance
	*/
	function & getNode($path) {
		$n=NULL;
		// getting path node heritage class list by specifity desc
		$classes=pathNode::heritage();
		foreach ($classes as $class) {
			//$detection=$class::selfDetector($path)
			$detection=call_user_func(array(&$class, "selfDetector"),$path);
			if ($detection) {
				// echo "<br />detected $class for $path ! ";
				$n=&new $class($path);
				return $n;
			}
		}
		return $n;
	}/**/

	/**
	* retrieve all subclasses and edventually declare a new subclass
	* If $class
	* @param string $class if provided, register this subclass
	* @param int $specificity 01-99, default 20 higher specificity override more generic classes
	* @access public
	* @static
	* @return array classes name with keys sheme specificity-classname, sorted on keys desc
	*/
	function heritage($class=NULL,$specificity=20) {
		static $classes;
		// basic classes
		$classes['01-pathnode']='pathnode';
		//$classes['02-filenode']='filenode';
		//$classes['02-foldernode']='foldernode';
		// adding subclass
		if (is_string($class) and is_int($specificity) and !in_array($class,$classes)) {
			$specificity=sprintf('%02d',$specificity);
			$class=strtolower($class);
			$classes["$specificity-$class"]=$class;
		}
		// sorting by specificity desc
		krsort($classes);
		return $classes;
	}/**/

	/**
	* sets a reference to parent node
	* @param pathNode &$node
	* @access public
	* @return bool
	*/
	function setParent(&$node) {
		if (!is_a($node,'pathnode')) return false;
		$this->_parent=&$node;
		return true;
	}/**/

	/**
	*
	* @access public
	* @return string basename
	*/
	function getBaseName() {
		return basename($this->path);
	}/**/

	/**
	* returns path from the main script directory
	* @access public
	* @return string
	*/
	function getRelativePath() {
        // getting relative path by substracting main script's dirname from absolute path
        return substr($this->getAbsolutePath()
			,strlen(dirname($_SERVER['SCRIPT_FILENAME']))+1);
	}

    /**
     * get absolute path
     * @return string
     */
    function getAbsolutePath() {
        $realpath=realpath($this->path);
		// a dirty hack for some web hosts using absolute paths without starting /
		if (PHP_OS!='WINNT' and substr($realpath,0,1)!='/')
			$realpath='/'.$realpath;
        return $realpath;
    }

	/**
	* get path as given in constructor
	* @access public
	* @return string
	*/
	function getPath() {
		return $this->path;
	}/**/

	/**
	* does the file exists ?
	* @access public
	* @return bool
	*/
	function exists() {
		return file_exists($this->path);
	}/**/

	/**
	*
	* @param
	* @access public
	* @return
	* /
	function () {

	}/**/
/*------------------------------------------------------------------------------
                                                                      properties
------------------------------------------------------------------------------*/
	/**
	* @var pathNode reference to parent node
	*/
	var $_parent;
	/**
	* @var bool
	*/
	//var $exists=false;
	/**
	* @var string file base name (without path)
	*/
	//var $basename;
	/**
	* @var string full path as given in constructor
	*/
	var $path;
	/**
	* @var string path from current main script
	*/
	//var $relative_path;
	/**
	* @var string path from server root
	*/
	// var $absolute_path;
/*------------------------------------------------------------------------------
                                                                 private methods
------------------------------------------------------------------------------*/
	/**
	* detects if path applies to self class.
	* subclasses HAVE to implement this method
	* @param string $path
	* @access protected
	* @return bool
	*/
	function selfDetector($path) {
		return false;
	}/**/

	/**
	* sets main path information properties from path
	* @param string $path
	* @access protected
	* @return bool
	*/
	function setInfo($path) {
		// translating windows path to standard ones
		$path=str_replace('\\','/',$path);
		$this->path=$path;
		return true;
	}/**/
}
?>